/**
   @file client/debutant/ia.hpp
   
   @brief Définit l'environnement d'une IA "débutante".
 */

#ifndef DEBUTANT_DEFINI

/**
   @brief Empêche les inclusions multiples.
 */
#define DEBUTANT_DEFINI

#include "joueur.hpp"
#include <QObject>
#include "client_jeu.hpp"
#include "option.hpp"
#include "partie_client.hpp"
#include "main.hpp"

class Ia: public QObject
{
  Q_OBJECT
public:
    enum EQUIPE{ATTAQUANT, DEFENSEUR};
  /**
     @brief Constructeur de base.

     L'IA construite de la sorte va demander à utiliser un certain nom
     à chaque fois qu'elle se trouve déconnectée, et ne va accepter
     les invitations que si elle connaît les personnes.

     @param nom Le nom qu'elle doit utiliser.
     @param equipe Les 4 noms de ses adversaires.
     @param parent Le QObject parent.
   */
  Ia(const QString & nom, const QVector<QString> & equipe, 
     QObject * parent = 0);
  /**
     @brief Initie la première connexion.
     
     @param hote Le nom d'hôte, que ce soit par adresse IP ou par nom
     de domaine.
     @param port Le numéro de port. Par défaut, 45678.
   */
  void connecter(QString hote, quint16 port);
private:
  const QString nom_souhaite;
  const QVector<QString> equipe_souhaitee;
  bool m_deconnexion_voulue;
  ClientJeu jeu;
  std::vector<int> pseudo_valeurs_cartes;
  std::vector<Joueur> joueurs;
  std::vector<Carte> cartes_jouees;
  unsigned int mon_id;
  Enchere contratFinal;
  EQUIPE equipe;
  
public slots:
  /**
     @brief Lance la connexion.
   */
  void deconnecte();
  /**
     @brief Lance la procédure d'identification.
  */
  void doit_identifier();
  /**
     @brief Quitte.
     
     @param nom Inutilisé : c'est le nom que j'avais demandé.
   */
  void identification_refusee(std::string nom);
  /**
     @brief Vérifie que je suis dans la bonne partie, ou me
     déconnecte.

     @param adv Les adversaires. Doivent correspondre à l'équipe
     demandée (dans le désordre).
     @see Ia::Ia
   */
  void adversaires(std::vector<std::string> adv);
  /**
     @brief Tente une enchere

     @param opt : c'est l'enchère maximale jusqu'à présent.
   */
  void doit_priser(Option<Enchere> opt);

  /**
     @brief Appel une carte une fois que l'enchère est accepté

     @param acceptees : cartes qui peuvent être appelées

  */
  void doit_appeler(std::vector<Carte> acceptees);

  void 	contrat_final (Enchere e);

  void doit_ecarter(std::vector<Carte> possibles, std::vector<Carte> atouts);

  /**
     @brief Tient mon jeu à jour.

     @param cartes Les cartes dont je dispose.
   */
  void jeu_est(std::vector<Carte> cartes);
  /**
     @brief Tente de jouer la carte suivante.
   */
  void doit_jouer();

  void tapis_change(Tapis tapis);

  void requete_refusee(Carte c);

  void numero_change(unsigned int );

  void partie_terminee(std::vector<int> scores);

signals:
  /**
     @brief Émis lorsque je dois m'identifier.

     @param nom Mon nom.
   */
  void formuler_identification(std::string nom);
  /**
     @brief Émis pour dire mon enchere.

     @param p Mon enchère
   */
  void formuler_prise(Enchere::Prise p);
  /**
     @brief Émis pour dire que je veux jouer une carte.

     @param c La carte à tester. C'est une des cartes de mon jeu, mais
     je ne sais pas si elle sera acceptée.
   */
  void formuler_requete(Carte c);
  /**
     @brief Permet à l'IA de dire quelle carte elle veut appeler

    */
  void formuler_appel(Carte requete);

  /**



    */
  void formuler_ecart(std::vector<Carte>);


  void deconnecter();
  /**
     @brief Émis pour dire que je souhaite me reconnecter.
   */
  void reconnecter();
  /**
     @brief Émis pour dire que j'ai fini mon travail.
   */
  void doit_quitter();
};

#endif
